﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using FimetContoDeposito.BLL.Metadata;
using FimetContoDeposito.BLL.Objects;
using FimetContoDeposito.DAL;
using GrayParrot.Core;

namespace FimetContoDeposito.BLL.Facades
{
    public class MovimentiFacade : FacadeBase<MovimentiFacade>
    {
        FCDContext m_ctx = null;

        public Repository<FCD_Movimenti, Guid> Repo { get; internal set; }


        public MovimentiFacade()
        {
        }

        public override void Initialize()
        {
            m_ctx = new FCDContext();
            m_ctx.Configuration.LazyLoadingEnabled = false;
            m_ctx.Configuration.ProxyCreationEnabled = false;

            Repo = this.GetRepository<FCD_Movimenti, Guid>(m_ctx);
        }

        public override void Dispose()
        {
            if (m_ctx != null)
            {
                m_ctx.Dispose();

                Repo.Dispose();
            }
        }

        public ReturnValue<bool> Add(FCD_Movimenti item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                if (item.Id == Guid.Empty)
                {
                    item.Id = Guid.NewGuid();
                }

                this.Repo.Add(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<bool> Edit(FCD_Movimenti item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                this.Repo.Edit(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<bool> Delete(FCD_Movimenti item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                this.Repo.Delete(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<FCD_Movimenti> Get(Guid id)
        {
            ReturnValue<FCD_Movimenti> retValue = new ReturnValue<FCD_Movimenti>(null);

            try
            {
                retValue.Value = this.Repo.Get(id);
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<FCD_Movimenti> Get(Guid id, string includes)
        {
            ReturnValue<FCD_Movimenti> retValue = new ReturnValue<FCD_Movimenti>();

            try
            {
                retValue.Value = this.Repo.Get(x => x.Id == id, null, includes).FirstOrDefault();
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<FCD_Movimenti>> GetAll()
        {
            ReturnValue<IQueryable<FCD_Movimenti>> retValue = new ReturnValue<IQueryable<FCD_Movimenti>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                retValue.Value = this.Repo.GetAll();
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<Cronologia>> GetMovimentiBags()
        {
            ReturnValue<IQueryable<Cronologia>> retValue = new ReturnValue<IQueryable<Cronologia>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_Movimentis
                           join d in m_ctx.FCD_AnagraficaDocumentis on x.IdDdt equals d.Id
                           where !x.Cancellato
                           select new Cronologia()
                           {
                               Id = x.Id,
                               NumeroDDT = x.FCD_AnagraficaDocumenti.NumeroDocumento,
                               DataDDT = x.DataRegistrazione,
                               IdCliente = x.FCD_Customer.Id,
                               Cliente = x.FCD_Customer.RagioneSociale,
                               TipoMovimento = (TipoMovimento)x.TipoMovimento
                           };

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<Cronologia> GetMovimentiBags(Guid idMovimento)
        {
            ReturnValue<Cronologia> retValue = new ReturnValue<Cronologia>(null);
            retValue.HasValue = false;

            try
            {
                var objs = from x in m_ctx.FCD_Movimentis
                           join d in m_ctx.FCD_AnagraficaDocumentis on x.IdDdt equals d.Id
                           where x.Id == idMovimento && !x.Cancellato 
                           select new Cronologia()
                           {
                               Id = x.Id,
                               NumeroDDT = x.FCD_AnagraficaDocumenti.NumeroDocumento,
                               DataDDT = x.DataRegistrazione,
                               IdCliente = x.FCD_Customer.Id,
                               Cliente = x.FCD_Customer.RagioneSociale,
                               TipoMovimento = (TipoMovimento)x.TipoMovimento
                           };

                if (objs.Any())
                {
                    retValue.Value = objs.FirstOrDefault();
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        /// <summary>
        /// Carica tutti i movimento non evasi in attesa di accettazione....
        /// </summary>
        /// <returns></returns>
        public ReturnValue<IQueryable<Cronologia>> GetMovimentiNonAccettatiBags()
        {
            ReturnValue<IQueryable<Cronologia>> retValue = new ReturnValue<IQueryable<Cronologia>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_Movimentis
                           join d in m_ctx.FCD_AnagraficaDocumentis on x.IdDdt equals d.Id
                           where !x.Cancellato && x.RegistratoDaUtente.Value && (!x.Accettato.Value || !x.Accettato.HasValue)
                           select new Cronologia()
                           {
                               Id = x.Id,
                               NumeroDDT = x.FCD_AnagraficaDocumenti.NumeroDocumento,
                               DataDDT = x.DataRegistrazione,
                               IdCliente = x.FCD_Customer.Id,
                               Cliente = x.FCD_Customer.RagioneSociale,
                               TipoMovimento = (TipoMovimento)x.TipoMovimento
                           };

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        /// <summary>
        /// Carica tutti i movimenti cliente non evasi per uno specifico magazzino...
        /// </summary>
        /// <param name="idMagazzino">The identifier magazzino.</param>
        /// <returns></returns>
        public ReturnValue<IQueryable<Cronologia>> GetMovimentiNonAccettatiBags(Guid idMagazzino)
        {
            ReturnValue<IQueryable<Cronologia>> retValue = new ReturnValue<IQueryable<Cronologia>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_Movimentis
                           join d in m_ctx.FCD_AnagraficaDocumentis on x.IdDdt equals d.Id
                           where !x.Cancellato 
                                 && x.TipoMovimento == 2
                                 && x.RegistratoDaUtente.Value 
                                 && (!x.Accettato.Value || !x.Accettato.HasValue)
                                 && x.Customer == idMagazzino
                           select new Cronologia()
                           {
                               Id = x.Id,
                               NumeroDDT = x.FCD_AnagraficaDocumenti.NumeroDocumento,
                               DataDDT = x.DataRegistrazione,
                               IdCliente = x.FCD_Customer.Id,
                               Cliente = x.FCD_Customer.RagioneSociale,
                               TipoMovimento = (TipoMovimento)x.TipoMovimento
                           };

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IEnumerable<Guid>> GetMovimentoDettaglioCarico(Guid idMovimento)
        {
            ReturnValue<IEnumerable<Guid>> retValue = new ReturnValue<IEnumerable<Guid>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_MovimentiDettaglios
                           where x.IdMovimento == idMovimento
                           select new { x.Id };

                if (objs.Any())
                {
                    List<Guid> m_ids = new List<Guid>();
                    foreach (var item in objs)
                    {
                        m_ids.Add(item.Id);
                    }

                    retValue.Value = m_ids;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IEnumerable<Guid>> GetMovimentoDettaglio(Guid idMovimento)
        {
            ReturnValue<IEnumerable<Guid>> retValue = new ReturnValue<IEnumerable<Guid>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_MovimentiDettaglios
                           where x.Id == idMovimento && !x.Cancellato
                           select new { x.Id };

                if (objs.Any())
                {
                    List<Guid> m_ids = new List<Guid>();
                    foreach (var item in objs)
                    {
                        m_ids.Add(item.Id);
                    }

                    retValue.Value = m_ids;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<CronologiaDettaglio>> GetMovimentiDettaglioBags(Guid idMovimento)
        {
            ReturnValue<IQueryable<CronologiaDettaglio>> retValue = new ReturnValue<IQueryable<CronologiaDettaglio>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_Movimentis
                           join d in m_ctx.FCD_MovimentiDettaglios on x.Id equals d.IdMovimento
                           join a in m_ctx.FCD_AnagraficaArticolis on d.Articolo equals a.Id
                           where x.Id == idMovimento && !d.Cancellato && (!x.Accettato.HasValue || !x.Accettato.Value)
                           select new CronologiaDettaglio()
                           {
                               Id = d.Id,
                               IdArticolo = a.Id,
                               Articolo = a.Descrizione,
                               Quantita = d.Quantita,
                               Prenotata = d.Prenotata,
                               Giacenza = d.QuantitaDisponibile,
                               Note = x.Note,
                               Foto = a.Foto,
                               Chiuso = d.Chiuso
                           };

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        /// <summary>
        /// Gets the proposta scarico.
        /// </summary>
        /// <param name="idArticolo">The identifier articolo.</param>
        /// <returns></returns>
        /// <remarks>
        /// Carica i movimenti di carico relativi all'articolo che hanno quantita > 0
        /// </remarks>
        public ReturnValue<IQueryable<MovimentoBag>> GetPropostaScarico(Guid idArticolo)
        {
            ReturnValue<IQueryable<MovimentoBag>> retValue = new ReturnValue<IQueryable<MovimentoBag>>(null);

            var objs = from x in m_ctx.FCD_Movimentis
                       join m in m_ctx.FCD_MovimentiDettaglios on x.Id equals m.IdMovimento
                       where m.Articolo == idArticolo && 
                             (x.TipoMovimento == 0 || (x.TipoMovimento == 2 && x.Accettato.Value)) && 
                             !m.Chiuso
                       orderby x.FCD_AnagraficaDocumenti.DataDocumento ascending
                       select new MovimentoBag()
                       {
                           Id = m.Id,
                           IdMovimentoCarico = m.IdMovimento,
                           Quantita = m.QuantitaDisponibile.Value,
                           Prenotata = m.Prenotata,
                           NumeroDocumento = x.FCD_AnagraficaDocumenti.NumeroDocumento,
                           DataDocumento = x.FCD_AnagraficaDocumenti.DataDocumento,
                           Chiuso = m.Chiuso
                       };

            if (objs.Any())
            {
                retValue.HasValue = true;
                retValue.Value = objs;
            }

            return retValue;
        }

        /// <summary>
        /// Elenco dei dettagli di uno scarico indicanti le quantità prelevati da movimenti di carico...
        /// </summary>
        /// <param name="idScarico">The identifier scarico.</param>
        /// <returns></returns>
        public ReturnValue<List<FCD_DettaglioScaricoBolla>> GetDettaglioScarico(Guid idScarico)
        {
            ReturnValue<List<FCD_DettaglioScaricoBolla>> retValue = new ReturnValue<List<FCD_DettaglioScaricoBolla>>(null);

            var objsDettaglioScaricoBolla = from x in m_ctx.FCD_DettaglioScaricoBollas
                                where x.IdScarico == idScarico && !x.Cancellato
                                select x;

            if (objsDettaglioScaricoBolla.Any())
            {
                retValue.HasValue = true;
                retValue.Value = objsDettaglioScaricoBolla.ToList();
            }

            return retValue;
        }

        /// <summary>
        /// Elenco dei dettagli di movimenti di carico coinvolti in un movimento di scarico...
        /// </summary>
        /// <param name="idDettaglioMovimento">The identifier dettaglio movimento.</param>
        /// <returns></returns>
        public ReturnValue<List<FCD_MovimentiDettaglio>> GetMovimentiDettaglioCarichiScarico(Guid idDettaglioMovimento)
        {
            ReturnValue<List<FCD_MovimentiDettaglio>> retValue = new ReturnValue<List<FCD_MovimentiDettaglio>>(null);

            var objsMovDettaglio = from x in m_ctx.FCD_MovimentiDettaglios
                                   where x.Id == idDettaglioMovimento && !x.Cancellato
                                   select x;

            if (objsMovDettaglio.Any())
            {
                retValue.HasValue = true;
                retValue.Value = objsMovDettaglio.ToList();
            }

            return retValue;
        }

        /// <summary>
        /// elenco dei dettagli movimento relativi ad un movimento di scarico...
        /// </summary>
        /// <param name="idDettaglioMovimento">The identifier dettaglio movimento.</param>
        /// <returns></returns>
        public ReturnValue<List<FCD_MovimentiDettaglio>> GetMovimentiDettaglioScarico(Guid idDettaglioMovimento)
        {
            ReturnValue<List<FCD_MovimentiDettaglio>> retValue = new ReturnValue<List<FCD_MovimentiDettaglio>>(null);

            var objsMovDettaglio = from x in m_ctx.FCD_MovimentiDettaglios
                                   where x.Id == idDettaglioMovimento
                                   select x;

            if (objsMovDettaglio.Any())
            {
                retValue.HasValue = true;
                retValue.Value = objsMovDettaglio.ToList();
            }

            return retValue;
        }

        public ReturnValue<bool> RipristinaDettagliMovimenti(Guid idScarico)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);

            using (var dbContextTransaction = m_ctx.Database.BeginTransaction())
            {
                try
                {
                    ReturnValue<List<FCD_DettaglioScaricoBolla>> objsDettaglioScaricoBolla = GetDettaglioScarico(idScarico);
                    if (objsDettaglioScaricoBolla.HasValue && objsDettaglioScaricoBolla.Value != null)
                    {
                        List<FCD_DettaglioScaricoBolla> m_scarichi = objsDettaglioScaricoBolla.Value;

                        foreach (FCD_DettaglioScaricoBolla s in m_scarichi)
                        {
                            ReturnValue<List<FCD_MovimentiDettaglio>> objsMovDettaglio = GetMovimentiDettaglioCarichiScarico(s.IdBollaCarico);

                            if (objsMovDettaglio.HasValue && objsMovDettaglio.Value != null)
                            {
                                List<FCD_MovimentiDettaglio> m_dettaglio = objsMovDettaglio.Value;

                                foreach (FCD_MovimentiDettaglio d in m_dettaglio)
                                {
                                    if (d.Chiuso)
                                    {
                                        d.Chiuso = false;
                                    }

                                    d.QuantitaDisponibile += s.Quantita;
                                }
                            }

                            s.Cancellato = true;
                            s.DataCancellazione = DateTime.Now;

                            //m_ctx.FCD_DettaglioScaricoBollas.Remove(s);
                        }
                    }

                    //
                    m_ctx.SaveChanges();

                    dbContextTransaction.Commit();

                    retValue.HasValue = true;
                    retValue.Value = true;
                }
                catch (Exception ex)
                {
                    dbContextTransaction.Rollback();

                    retValue.HasError = true;
                    retValue.Error = ex;
                }
            }

            return retValue;
        }

        /// <summary>
        /// Ritorna il numero di elementi presenti in un movimento di scarico
        /// </summary>
        /// <param name="idScarico">Identificatore dell'elemento di un movimento di scarico</param>
        /// <returns></returns>
        public ReturnValue<int> GetNumeroElementiScarico(Guid idScarico)
        {
            ReturnValue<int> retValue = new ReturnValue<int>(-1);

            var objs = from x in m_ctx.FCD_MovimentiDettaglios
                       where x.Id == idScarico
                       select x;

            if (objs.Any())
            {
                FCD_MovimentiDettaglio obj = objs.FirstOrDefault();
                Guid m_idMovimentoScarico = obj.IdMovimento;

                retValue.Value = m_ctx.FCD_MovimentiDettaglios.Count(x => x.IdMovimento == m_idMovimentoScarico);
                retValue.HasValue = true;
            }

            return retValue;
        }

        /// <summary>
        /// Imposta un movimento come cancellato...
        /// </summary>
        /// <param name="idMovimento">The identifier movimento.</param>
        /// <returns></returns>
        public ReturnValue<bool> SetCancellato(Guid idMovimento)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);

            try
            {
                var objs = from x in m_ctx.FCD_Movimentis
                           where x.Id == idMovimento
                           select x;

                if (objs.Any())
                {
                    FCD_Movimenti obj = objs.FirstOrDefault();
                    obj.Cancellato = true;
                    obj.DataCancellazione = DateTime.Now;

                    m_ctx.SaveChanges();

                    retValue.HasValue = true;
                    retValue.Value = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<bool> AccettaMovimentoCliente(Guid idMovimento, TipoMovimento tipoMovimento, string operatore)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);

            switch (tipoMovimento)
            {
                case TipoMovimento.OrdineCarico:
                    {
                        ReturnValue<FCD_Movimenti> m_mov = this.Get(idMovimento);

                        if (m_mov.HasValue && m_mov.Value != null)
                        {
                            m_mov.Value.Accettato = true;
                            m_mov.Value.DataAccettazione = DateTime.Now;
                            m_mov.Value.OperatoreAccettazione = operatore;

                            m_ctx.SaveChanges();

                            retValue.HasValue = true;
                            retValue.Value = true;
                        }
                    }
                    break;
                case TipoMovimento.OrdineScarico:
                    {
                        ReturnValue<FCD_Movimenti> m_mov = this.Get(idMovimento);

                        if (m_mov.HasValue && m_mov.Value != null)
                        {
                            m_mov.Value.Accettato = true;
                            m_mov.Value.DataAccettazione = DateTime.Now;
                            m_mov.Value.OperatoreAccettazione = operatore;

                            m_ctx.SaveChanges();

                            retValue.HasValue = true;
                            retValue.Value = true;
                        }
                    }
                    break;
                default:
                    break;
            }

            return retValue;
        }

        /// <summary>
        /// Ritorna i dati del documento relativo ad un movimento di carico...
        /// </summary>
        /// <param name="idMovimentoCarico">The identifier movimento carico.</param>
        /// <remarks>Utilizzato per la stampa del movimenento di carico</remarks>
        /// <returns></returns>
        public List<FCD_GetDocumentoCaricoReturnModel> GetDocumentoMovimentoCarico(Guid idMovimentoCarico)
        {
            List<FCD_GetDocumentoCaricoReturnModel> retValue = null;

            var objs = from x in m_ctx.FCD_GetDocumentoCarico(idMovimentoCarico)
                      select x;

            if (objs.Any())
            {
                retValue = objs.ToList();
            }

            return retValue;
        }

        /// <summary>
        /// Ritorna i dati del documento relativo ad un movimento di scarico...
        /// </summary>
        /// <param name="idMovimentoScarico">The identifier movimento scarico.</param>
        /// <remarks>Utilizzato per la stampa del movimenento di carico</remarks>
        /// <returns></returns>
        public List<FCD_GetDocumentoScaricoReturnModel> GetDocumentoMovimentoScarico(Guid idMovimentoScarico)
        {
            List<FCD_GetDocumentoScaricoReturnModel> retValue = null;

            var objs = from x in m_ctx.FCD_GetDocumentoScarico(idMovimentoScarico)
                       select x;

            if (objs.Any())
            {
                retValue = objs.ToList();
            }

            return retValue;
        }

        /// <summary>
        /// Gets the dettaglio movimento carico edit.
        /// </summary>
        /// <param name="idMovimentoCarico">The identifier movimento carico.</param>
        /// <returns></returns>
        public List<FCD_GetDettaglioMovimentoCaricoReturnModel> GetDettaglioMovimentoCaricoEdit(Guid idMovimentoCarico)
        {
            List<FCD_GetDettaglioMovimentoCaricoReturnModel> retValue = null;

            var objs = from x in m_ctx.FCD_GetDettaglioMovimentoCarico(idMovimentoCarico)
                       select x;

            if (objs.Any())
            {
                retValue = objs.ToList();
            }

            return retValue;
        }

        public List<FCD_GetDettaglioMovimentoCaricoClienteReturnModel> GetDettaglioMovimentoCaricoClienteEdit(Guid idMovimentoCarico)
        {
            List<FCD_GetDettaglioMovimentoCaricoClienteReturnModel> retValue = null;

            var objs = from x in m_ctx.FCD_GetDettaglioMovimentoCaricoCliente(idMovimentoCarico)
                       select x;

            if (objs.Any())
            {
                retValue = objs.ToList();
            }

            return retValue;
        }

        /// <summary>
        /// Ritorna il dettaglio di un movimento di carico per come serve al report dei movimenti di carico
        /// </summary>
        /// <param name="idMovimentoCarico">The identifier movimento carico.</param>
        /// <remarks>Utilizzato per la stampa del movimenento di carico</remarks>
        /// <returns></returns>
        public List<GetDettaglioMovimentoReturnModel> GetDettaglioMovimentoCarico(Guid idMovimentoCarico)
        {
            List<GetDettaglioMovimentoReturnModel> retValue = null;

            var objs = from x in m_ctx.GetDettaglioMovimento(idMovimentoCarico)
                       select x;

            if (objs.Any())
            {
                retValue = objs.ToList();
            }

            return retValue;
        }

        /// <summary>
        /// Ritorna il dettaglio di un movimento di scarico...
        /// </summary>
        /// <param name="idMovimentoScarico">The identifier movimento scarico.</param>
        /// <remarks>Utilizzato per la stampa del movimenento di carico</remarks>
        /// <returns></returns>
        public List<FCD_GetDettaglioMovimentoScaricoReturnModel> GetDettaglioMovimentoScarico(Guid idMovimentoScarico)
        {
            List<FCD_GetDettaglioMovimentoScaricoReturnModel> retValue = null;

            var objs = from x in m_ctx.FCD_GetDettaglioMovimentoScarico(idMovimentoScarico)
                       select x;

            if (objs.Any())
            {
                retValue = objs.ToList();
            }

            return retValue;
        }

        public ReturnValue<List<ModificaMovimentoBag>> CercaMovimentoCarico(System.Linq.Expressions.Expression<Func<FCD_Movimenti, bool>> predicate)
        {
            ReturnValue<List<ModificaMovimentoBag>> m_retValue = new ReturnValue<List<ModificaMovimentoBag>>(null);

            var objs = from x in m_ctx.FCD_Movimentis.Where(predicate)
                       where x.TipoMovimento == (int)TipoMovimento.Carico
                       select new ModificaMovimentoBag()
                       {
                           Id = x.Id,
                           Customer = x.FCD_Customer.RagioneSociale,
                           DataDocumento = x.FCD_AnagraficaDocumenti.DataDocumento,
                           DataMovimento = x.DataMovimento.Value,
                           NumeroDocumento = x.FCD_AnagraficaDocumenti.NumeroDocumento,
                           TipoDocumento = x.FCD_AnagraficaDocumenti.FCD_TipologiaDocumento.Descrizione
                       };

            if (objs.Any())
            {
                m_retValue.HasValue = true;
                m_retValue.Value = objs.ToList();
            }

            return m_retValue;
        }

        public ReturnValue<List<ModificaMovimentoBag>> CercaMovimentoToEdit(System.Linq.Expressions.Expression<Func<FCD_Movimenti, bool>> predicate, TipoMovimento tipoMovimento)
        {
            ReturnValue<List<ModificaMovimentoBag>> m_retValue = new ReturnValue<List<ModificaMovimentoBag>>(null);

            var objs = from x in m_ctx.FCD_Movimentis.Where(predicate)
                       where x.TipoMovimento == (int)tipoMovimento 
                             //&& !x.Chiuso
                       select new ModificaMovimentoBag()
                       {
                           Id = x.Id,
                           Customer = x.FCD_Customer.RagioneSociale,
                           IdDocumento = x.FCD_AnagraficaDocumenti.Id,
                           DataDocumento = x.FCD_AnagraficaDocumenti.DataDocumento,
                           DataMovimento = x.DataMovimento.Value,
                           NumeroDocumento = x.FCD_AnagraficaDocumenti.NumeroDocumento,
                           TipoDocumento = x.FCD_AnagraficaDocumenti.FCD_TipologiaDocumento.Descrizione,
                           Chiuso = x.Chiuso,
                           Cancellato = x.Cancellato
                       };

            if (objs.Any())
            {
                m_retValue.HasValue = true;
                m_retValue.Value = objs.ToList();
            }

            return m_retValue;
        }

        /// <summary>
        /// Imposta lo stato del movimento di carico...
        /// </summary>
        /// <param name="idMovimento">The identifier movimento.</param>
        /// <returns></returns>
        public ReturnValue<bool> ImpostaStatoCarico(Guid idMovimento)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);

            try
            {
                m_ctx.FCD_ImpostaStatoMovimentoCarico(idMovimento);

                retValue.Value = true;
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.Message = ex.Message;
                retValue.Error = ex;
                retValue.Value = false;
                retValue.HasError = true;
            }

            return retValue;
        }

        /// <summary>
        /// Cancella tutti gli ordini di carico non evasi di un magazzino...
        /// </summary>
        /// <param name="idMagazzino">The identifier magazzino.</param>
        /// <returns></returns>
        public ReturnValue<bool> CancellaOrdiniNonEvasi(Guid idMagazzino)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);

            try
            {
                m_ctx.FCD_CancellaOrdiniNonEvasi(idMagazzino);

                retValue.Message = "Ordini di carico cancellati";
                retValue.Value = true;
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.Message = ex.Message;
                retValue.Error = ex;
                retValue.Value = false;
                retValue.HasError = true;
            }

            return retValue;
        }

        public ReturnValue<bool> CancellaOrdineNonEvaso(Guid idMagazzino, Guid idMovimento)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);

            try
            {
                m_ctx.FCD_CancellaOrdineNonEvaso(idMagazzino, idMovimento);

                retValue.Message = "Ordine di carico cancellato";
                retValue.Value = true;
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.Message = ex.Message;
                retValue.Error = ex;
                retValue.Value = false;
                retValue.HasError = true;
            }

            return retValue;
        }

        public ReturnValue<bool> CancellaDettaglioOrdineNonEvaso(Guid idMovimentoDettaglio)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);

            try
            {
                var objs = from x in m_ctx.FCD_MovimentiDettaglios
                           where x.Id == idMovimentoDettaglio
                           select x;

                if (objs.Any())
                {
                    FCD_MovimentiDettaglio obj = objs.FirstOrDefault();

                    obj.Cancellato = true;

                    m_ctx.SaveChanges();

                    //
                    retValue.Message = "Dettaglio Ordine di carico cancellato";
                    retValue.Value = true;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.Message = ex.Message;
                retValue.Error = ex;
                retValue.Value = false;
                retValue.HasError = true;
            }

            return retValue;
        }

        public List<FCD_CaricaDatiCronologiaReturnModel> GetCronologia()
        {
            List<FCD_CaricaDatiCronologiaReturnModel> retValue = null;

            var objs = from x in m_ctx.FCD_CaricaDatiCronologia()
                       select x;

            if (objs.Any())
            {
                retValue = objs.ToList();
            }

            return retValue;
        }

        public ReturnValue<bool> CheckArticoloInMovimento(Guid idArticolo)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);
            retValue.HasValue = true;

            try
            {
                var objs = from x in m_ctx.FCD_MovimentiDettaglios.Where(x => x.Articolo == idArticolo)
                           select x;

                if (objs.Any())
                {
                    retValue.HasValue = true;
                    retValue.Value = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Message = ex.Message;
            }

            return retValue;
        }

        /// <summary>
        /// Imposta le informazioni di contributo...
        /// </summary>
        /// <param name="idElemento">The identifier elemento.</param>
        /// <param name="contributo">The contributo.</param>
        /// <returns></returns>
        //public ReturnValue<bool> SetInformazioniContributo(Guid idElemento, ContributoScarico contributo)
        //{
        //    ReturnValue<bool> retValue = new ReturnValue<bool>(false);

        //    try
        //    {
        //        ReturnValue<FCD_Movimenti> m_rvMD = this.Get(idElemento);

        //        if (m_rvMD.HasValue && m_rvMD.Value != null)
        //        {
        //            m_rvMD.Value.QtaFatt = contributo.QtaFatt;
        //            m_rvMD.Value.MovimentoPezzi = contributo.MovimentoPezzi;
        //            m_rvMD.Value.MovimentoKg = contributo.MovimentoKg;

        //            m_ctx.SaveChanges();

        //            retValue.HasValue = true;
        //            retValue.Value = true;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        retValue.HasError = true;
        //        retValue.Error = ex;
        //    }

        //    return retValue;
        //}
    }
}
